#include "stdafx.h"
#include "BaseLogicGameMap.h"
#include "LgSpriteStatic.h"
#include "FlyRotateLgSprite.h"
#include "FlyMoveLgSprite.h"
#include "PlayerLg.h"
#include "LgSpriteGate.h"
#include "LgSpriteKey.h"
#include "LgSpriteProperty.h"
#include "LgSpritePropertyGem.h"
BaseLogicGameMap::BaseLogicGameMap(void):m_lStartTime(0),m_lLastTime(0),
	m_bGameOver(true),m_nCurrentProperty(0),m_vfPropInterval(NULL)
{
	fGravity=40;
}

BaseLogicGameMap::~BaseLogicGameMap(void)
{
	UnloadTheMap();
}
bool BaseLogicGameMap::GameStart(DWORD dwCurrentTime)
{
	m_lStartTime=dwCurrentTime;
	m_bGameOver=false;
	unsigned int i=0;
	for (i=0;i<m_vecPlayerLgSprite.size();i++){
		m_vecPlayerLgSprite[i]->m_nInvincibleDieBeginTime=dwCurrentTime;
		m_vecPlayerLgSprite[i]->SetAllLGSprites(m_listLgSprites);
	}

	//property
	srand(dwCurrentTime);
	m_nPropCount=m_vecProperties.size();
	m_vfPropInterval=new float[m_nPropCount];
	AssignPropertiesTimes(m_vfPropInterval,m_nPropCount,m_GameTime);

	Disorder(m_vecProperties);

	return true;
}
void BaseLogicGameMap::AssignPropertiesTimes(float *fInterval, unsigned int nSize, DWORD nGameTime)
{
	float fTotal=0.0f;
	unsigned int i=0;
	for (i=0;i<nSize;i++){
		fInterval[i]=static_cast<float>(rand())/32767.0f;
		fTotal+=fInterval[i];
	}

	//first 5 second and last 20-5 second don't popup properties.
	float k=(nGameTime-20)/fTotal;
	fTotal=0.0f;
	for (i=0;i<nSize;i++){
		fInterval[i]=fInterval[i]*k+fTotal+5;
		fTotal=fInterval[i]-5;
	}
}

void BaseLogicGameMap::UnloadTheMap()
{
	list<BaseLogicSprite*>::iterator itLg;
	for (itLg=m_listLgSprites.begin();itLg!=m_listLgSprites.end();itLg++){
		SAFE_DELETE(*itLg);
	}
	m_listLgSprites.clear();
	m_vecPlayerLgSprite.clear();

	m_vecProperties.clear();
	SAFE_DELETE(m_vfPropInterval)

	m_bGameOver=true;
	m_lLastTime=0;
}
void BaseLogicGameMap::UpdateAllLgSprite(DWORD dwCurrentTime)
{
	m_lLastTime=dwCurrentTime-m_lStartTime;
	list<BaseLogicSprite*>::iterator it;
	for (it=m_listLgSprites.begin();it!=m_listLgSprites.end();it++){
		(*it)->Update(dwCurrentTime);
	}
	//update properties
	if (m_nCurrentProperty<m_nPropCount){
		if (m_lLastTime>m_vfPropInterval[m_nCurrentProperty]*1000.0f){
			m_vecProperties[m_nCurrentProperty]->PopUp(0,m_nWidth,m_nHeight);
			m_nCurrentProperty++;
		}
	}
	if(m_lLastTime>m_GameTime*1000){
		m_bGameOver=true;
	}
}

bool BaseLogicGameMap::CreateSpritesByStatic(
	const vector<BalloonElemnet_t>& vecBalloonElemnets,//in
	const list<Static_Element_InMap_t>& listStaticElements//in
	)
{
	list<Static_Element_InMap_t>::const_iterator itSE;
	for (itSE=listStaticElements.begin();itSE!=listStaticElements.end();itSE++)
	{
		BalloonElemnet_t stBE;
		stBE=vecBalloonElemnets[itSE->ID-1];
		CreateSpriteByStatic(stBE,*itSE);
	}
	return true;
}
bool BaseLogicGameMap::CreateSpritesByFly(
	const vector<BalloonElemnet_t>& vecBalloonElemnets,
	const list<Fly_Element_InMap_t>& listFlyElements)
{
	list<Fly_Element_InMap_t>::const_iterator itFE;
	for (itFE=listFlyElements.begin();itFE!=listFlyElements.end();itFE++)
	{
		BalloonElemnet_t stBE;
		stBE=vecBalloonElemnets[itFE->ID-1];
		CreateSpriteByFly(stBE,*itFE);
	}
	return true;
}
bool BaseLogicGameMap::CreatePlayers(
	const list<Static_Element_InMap_t>& listStaticElements//in
	)
{
	list<Static_Element_InMap_t>::const_iterator itFE;
	for (itFE=listStaticElements.begin();itFE!=listStaticElements.end();itFE++)
	{
		CharacterProperty_t st;
		CreatePlayer(*itFE,st);
	}
	PlayerLg::SetMapSize(m_nWidth,m_nHeight);
	return  true;
}
BaseLogicSprite* BaseLogicGameMap::CreateSpriteByStatic(
	const BalloonElemnet_t& stBalloonElemnet,//in
	const Static_Element_InMap_t& stStaticElement//in
	)
{
	BaseLogicSprite* pLgSprite=NULL;
	if (stBalloonElemnet.listPoint.size()>0)
	{
		pLgSprite=new LgSpriteStatic(stBalloonElemnet.listPoint);
		if (pLgSprite)
		{
			D3DXVECTOR2 pos((float)stStaticElement.point.x,(float)stStaticElement.point.y);
			pLgSprite->SetPos(pos);
			m_listLgSprites.push_back(pLgSprite);
		}
	}	
	if (stBalloonElemnet.listRect.size()>0)
	{
		pLgSprite=new LgSpriteStatic(stBalloonElemnet.listRect);
		if (pLgSprite)
		{
			D3DXVECTOR2 pos((float)stStaticElement.point.x,(float)stStaticElement.point.y);
			pLgSprite->SetPos(pos);
			m_listLgSprites.push_back(pLgSprite);
		}
	}
	return pLgSprite;
}

BaseLogicSprite* BaseLogicGameMap::CreateSpriteByGate( 
	const BalloonElemnet_t& stBalloonElemnet,
	const Static_Element_InMap_t& stStaticElement)
{
	LgSpriteGate* pLgSprite=NULL;
	if (stBalloonElemnet.listRect.size()>0)
	{
		pLgSprite=new LgSpriteGate(stBalloonElemnet.listRect);
		if (pLgSprite)
		{
			list<BaseLogicSprite*>::const_iterator it;
			for (it=m_listLgSprites.begin();it!=m_listLgSprites.end();it++)
			{//find the key, maybe can't find
				if ((*it)->GetClassTpye()==eLgSpriteKey){
					dynamic_cast<LgSpriteKey*>(*it)->SetGate(pLgSprite);
				}
			}
			D3DXVECTOR2 pos((float)stStaticElement.point.x,(float)stStaticElement.point.y);
			pLgSprite->SetPos(pos);
			m_listLgSprites.push_back(pLgSprite);
		}

	}
	return pLgSprite;
}

BaseLogicSprite* BaseLogicGameMap::CreateSpriteByPrimer( 
	const BalloonElemnet_t& stBalloonElemnet,
	const Static_Element_InMap_t& stStaticElement)
{
	BaseLogicSprite* pLgSprite=NULL;
	if (stBalloonElemnet.listRect.size()>0)
	{
		if (stStaticElement.nType==2)
		{//2:key, 1:cup
			pLgSprite=new LgSpriteKey(stBalloonElemnet.listRect);
			if (pLgSprite)
			{
				list<BaseLogicSprite*>::const_iterator it;
				for (it=m_listLgSprites.begin();it!=m_listLgSprites.end();it++)
				{//find the gate, maybe can't find
					if ((*it)->GetClassTpye()==eLgSpriteGate){
						dynamic_cast<LgSpriteKey*>(pLgSprite)->SetGate(dynamic_cast<LgSpriteGate*>(*it));
					}
				}
				D3DXVECTOR2 pos((float)stStaticElement.point.x,(float)stStaticElement.point.y);
				pLgSprite->SetPos(pos);
				m_listLgSprites.push_back(pLgSprite);
			}
		}
	}	
	return pLgSprite;
}

BaseLogicSprite* BaseLogicGameMap::CreateSpriteByProperty(short nType,
	int nWidth,int nHeight,const Property_InMap_t& stProperty)
{
	LgSpriteProperty* pLgSprite=NULL;
	RectInBalloonElemnet_t stRect;
	stRect.nProperty=HPDisappear|HPProperty|nType<<16;
	stRect.rect.left=-nWidth/2;
	stRect.rect.top=-nHeight/2;
	stRect.rect.right=nWidth/2;
	stRect.rect.bottom=nHeight/2;
	if( eGem2==nType||eGem3==nType||eGem5==nType||
		eGem10==nType||eGemChange==nType){
		pLgSprite=new LgSpritePropertyGem(stProperty.nSpeed,stProperty.nFlyAreaX,stRect,m_nHeight);
	}else{
		pLgSprite=new LgSpriteProperty(stProperty.nSpeed,stProperty.nFlyAreaX,stRect,m_nHeight);
	}
	if (!pLgSprite){
		return NULL;
	}
	m_vecProperties.push_back(pLgSprite);
	m_listLgSprites.push_back(pLgSprite);
	return pLgSprite;
}
BaseLogicSprite* BaseLogicGameMap::CreateSpriteByFly(
	const BalloonElemnet_t& stBalloonElemnet,
	const Fly_Element_InMap_t& stFlyElements)
{
	BaseLogicSprite* pLgSprite=NULL;
	if (stBalloonElemnet.listRect.size()>0){
		if (eRotate==stFlyElements.nFlyType){
			pLgSprite=new FlyRotateLgSprite((float)stFlyElements.nSpeed,(float)stFlyElements.nRadian,
				(float)stFlyElements.pointCenter.x,(float)stFlyElements.pointCenter.y,
				(float)stFlyElements.nRadius,stBalloonElemnet.listRect);
		}
		if (eMove==stFlyElements.nFlyType){
			if (stFlyElements.rect.left==stFlyElements.rect.right && stFlyElements.rect.top==stFlyElements.rect.bottom){
				pLgSprite=new LgSpriteStatic(stBalloonElemnet.listRect);
				if (!pLgSprite){
					return NULL;
				}
				D3DXVECTOR2 pos((float)stFlyElements.rect.left,(float)stFlyElements.rect.top);
				pLgSprite->SetPos(pos);
			}else{
				pLgSprite=new FlyMoveLgSprite(stFlyElements.nTime,stFlyElements.nPastTime,stFlyElements.rect,stFlyElements.nInterVal1,stFlyElements.nInterVal2,stBalloonElemnet.listRect);
			}
		}
		if (pLgSprite){
			m_listLgSprites.push_back(pLgSprite);
		}
	}
	return pLgSprite;
}
BaseLogicSprite* BaseLogicGameMap::CreatePlayer(
	const Static_Element_InMap_t& stStaticElements,
	const CharacterProperty_t& st,bool bCycleMap)
{
	PlayerLg *pLgSprite=new PlayerLg(st,bCycleMap);
	if (!pLgSprite){
		return NULL;
	}
	D3DXVECTOR2 pos;
	pos.x=(float)stStaticElements.point.x;
	pos.y=(float)stStaticElements.point.y;
	pLgSprite->SetPos(pos);

	PlayerLg::SetMapSize(m_nWidth,m_nHeight);

	m_listLgSprites.push_back(pLgSprite);
	m_vecPlayerLgSprite.push_back(pLgSprite);

	//pLgSprite->m_nGroup=rand()%2;
	return pLgSprite;
}

D3DXVECTOR2 BaseLogicGameMap::GetPlayerPos(unsigned short n)
{
	if (n>=m_vecPlayerLgSprite.size())
	{
		return D3DXVECTOR2(0.0f,0.0f);
	}
	return m_vecPlayerLgSprite[n]->GetPos();
}
PlayerLg* BaseLogicGameMap::GetPlayer(unsigned short n)
{
	if (n>=m_vecPlayerLgSprite.size())
	{
		return NULL;
	}
	return m_vecPlayerLgSprite[n];
}
unsigned short BaseLogicGameMap::GetNumOfPlayer()
{
//	return 2;
	return m_vecPlayerLgSprite.size();
}
